#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/6/19 16:12
# @Author  : CoderCharm
# @File    : response.py
# @Software: PyCharm
# @Desc    :
"""
定义返回的状态

# 看到文档说这个orjson 能压缩性能(squeezing performance)
https://fastapi.tiangolo.com/advanced/custom-response/#use-orjsonresponse

It's possible that ORJSONResponse might be a faster alternative.

# 安装
pip install --upgrade orjson

测试了下，序列化某些特殊的字段不友好，比如小数
TypeError: Type is not JSON serializable: decimal.Decimal
"""
from fastapi import FastAPI, Request
from fastapi import status
from fastapi.responses import JSONResponse, Response, ORJSONResponse

from typing import Union, Dict, List


class HTTPExceptionCustom(Exception):

    def __init__(self, code: int, message: str, data: Dict):
        self.code = code
        self.message = message
        self.data = data
        self.headers = {"WWW-Authenticate": "Bearer"}


def register_http_exception(app: FastAPI):
    @app.exception_handler(HTTPExceptionCustom)
    def unicorn_exception_handler(request: Request, exc: HTTPExceptionCustom):
        return ORJSONResponse(
            status_code=exc.code,
            content={
                'code': exc.code,
                'message': exc.message,
                'data': exc.data,
            }
        )


def resp_login(access_token: str, token_type: str = "bearer", ) -> Response:
    return ORJSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            "access_token": access_token,
            "token_type": token_type,
        }
    )


def resp_200(data: Union[Dict, List, str] = None, *, message: str = "Success") -> Response:
    # raise HTTPExceptionCustom(
    #     code=status.HTTP_200_OK,
    #     message=message,
    #     data=data
    # )
    return ORJSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            'code': status.HTTP_200_OK,
            'message': message,
            'data': data,
        }
    )


def resp_400(message: str = "Bad Request") -> Response:
    raise HTTPExceptionCustom(
        code=status.HTTP_400_BAD_REQUEST,
        message=message,
        data={}
    )


def resp_401(message: str = "Invalid authentication credentials") -> Response:
    raise HTTPExceptionCustom(
        code=status.HTTP_401_UNAUTHORIZED,
        message=message,
        data={}
    )


def resp_403(message: str = "Operation not permitted") -> Response:
    raise HTTPExceptionCustom(
        code=status.HTTP_403_FORBIDDEN,
        message=message,
        data={}
    )


def resp_404(message: str = "Page Not Found") -> Response:
    raise HTTPExceptionCustom(
        code=status.HTTP_404_NOT_FOUND,
        message=message,
        data={}
    )


def resp_500(message: str = "Server internal error") -> Response:
    raise HTTPExceptionCustom(
        code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        message=message,
        data={}
    )


# 自定义
def resp_5000(data: Union[list, dict, str]) -> Response:
    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={
            'code': 5000,
            'message': "Token failure",
            'data': data,
        }
    )
